package com.yanqu.road.server.manger.activity.greattrade;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.args.ValueFourParamArgs;
import com.yanqu.road.entity.activity.greattrade.*;
import com.yanqu.road.entity.activity.greattrade.config.GreatTradeEventInfo;
import com.yanqu.road.entity.activity.greattrade.config.GreatTradeGoodsInfo;
import com.yanqu.road.entity.activity.greattrade.config.GreatTradeSkillsInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.greattrade.GreatTradeModule;
import com.yanqu.road.server.gameplayer.module.activity.greattrade.IndustryResult;
import com.yanqu.road.server.gameplayer.module.activity.greattrade.SaltWorksResult;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class GreatTradeMgr extends TempMgr {

    static GreatTradeConfig config;

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static ActivityInfo getActivityInfo() {
        if(config == null) {
            return null;
        }
        return config.getActivityInfo();
    }

    public static void reloadActivityData() {
        getLogger().info("reload GreatTrade Activity start");
        ActivityInfo tempActivityInfo;
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.GreatTradeActivity.getValue());
        if (openActivityInfoList.isEmpty()) {
            getLogger().info("no GreatTrade Activity in show time");
            config = null;
        } else {
            tempActivityInfo = openActivityInfoList.get(0);

            GreatTradeConfig configTemp = new GreatTradeConfig();
            configTemp.setActivityInfo(tempActivityInfo);

            boolean initSuccess = configTemp.init();

            if(!initSuccess){
                config = null;
                return;
            }

            config = configTemp;
        }
        getLogger().info("reload GreatTrade Activity finish");

        // 在线玩家下发数据
        for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
            GreatTradeModule module = gamePlayer.getModule(GreatTradeModule.class);
            module.syncConfig();
            module.initUserData();
            module.syncUserData();
        }
    }


    public static GreatTradeConfig getConfig() {
        return config;
    }


    public static void copy(GreatTradeSimpleStatus source, GreatTradeSimpleStatus target){
        target.setTradeFinish(source.isTradeFinish());
        target.setCurYear(source.getCurYear());
        target.setBagCap(source.getBagCap());
        target.setTitle(source.getTitle());
        target.setAge(source.getAge());
        target.setHealth(source.getHealth());
        target.setAssets(source.getAssets());
        target.setLastAssets(source.getLastAssets());
        target.setSilver(source.getSilver());
        target.setPrestige(source.getPrestige());
        target.setBirth(source.getBirth());
        target.setOutTimes(source.getOutTimes());
        target.setTotalAddOutTimes(source.getTotalAddOutTimes());
        target.setDayResetTime(source.getDayResetTime());
        target.setHealthTimes(source.getHealthTimes());
        target.setEventSelectTimes(source.getEventSelectTimes());
        target.setExMaxHealth(source.getExMaxHealth());
        target.setRandomEventId(source.getRandomEventId());
        target.setRisk(source.getRisk());
        target.setBanquetTimes(source.getBanquetTimes());
        target.setSellTimes(source.getSellTimes());
        target.setIll(source.isIll());
        target.setTotalOutTimes(source.getTotalOutTimes());
        target.setBrokenTimes(source.getBrokenTimes());
        target.setStatus(source.getStatus());
        target.setMaxAssets(source.getMaxAssets());
        for (Map.Entry<Integer, String> entry : source.getSellMoney().entrySet()) {
            String val = entry.getValue();
            target.getSellMoney().put(entry.getKey(), val);
        }
        target.setPrestigeLv(source.getPrestigeLv());
        target.setGooodsAddSum(source.getGooodsAddSum());
        target.setYingLi(source.getYingLi());
    }

    /**
     * 市场价格最新波动
     */
    public static long getPriceCompare(List<Map<Integer, Long>> industryPrice, int id) {
        if(industryPrice.size() < 2){
            return 0;
        }
        int size = industryPrice.size();
        if(!industryPrice.get(size - 1).containsKey(id)){
            return 0;
        }
        if(!industryPrice.get(size - 2).containsKey(id)){
            return 0;
        }
        return industryPrice.get(size - 1).get(id) - industryPrice.get(size - 2).get(id);
    }

    /**
     * 计算资产
     */
    public static void calUserAssert(UserGreatTradeData userData, GreatTradeSimpleStatus status, GreatTradeConfig config) {
        BigInteger assets = new BigInteger(status.getSilver());

        Map<Integer, Integer> goodsPriceMap = userData.getGoodsPriceList();

        for (GreatTradeGoods goods : userData.getGoodsList()) {
            if(goodsPriceMap.containsKey(goods.getId())){
                assets = assets.add(BigInteger.valueOf(goods.getNum()).multiply(BigInteger.valueOf(goodsPriceMap.get(goods.getId()))));
            }else {
                assets = assets.add(new BigInteger(goods.getPrice()));
            }
        }

        if(userData.getIndustry().getId() > 0){
            GreatTradeGoodsInfo goodsInfo = config.getGreatTradeGoodsInfo(userData.getIndustry().getId());
            if(goodsInfo != null) {
                assets = BigInteger.valueOf(userData.getIndustry().getPrice()).multiply(BigInteger.valueOf(userData.getIndustry().getShares())).add(assets);
            }
        }

        //盐场
        for (Map.Entry<Integer, GreatTradeSaltWorks> saltWorksEntry : userData.getSaltWorksMap().entrySet()) {
            if(saltWorksEntry.getValue().getSealOrSell() ==1 || GreatTradeMgr.getSaltWorksReserves(userData, saltWorksEntry.getValue(), config) <= 0 || saltWorksEntry.getValue().getSealOrSell() == 3){
                continue;
            }
            assets = assets.add(getSaltWorksSellPrice(config, saltWorksEntry.getValue()));
        }

        status.setAssets(assets.toString());

        //记录最高资产
        BigInteger max = new BigInteger(status.getMaxAssets());
        if(assets.compareTo(max) > 0) {
            status.setMaxAssets(assets.toString());
        }
    }

    /**
     * 盐场出售价格
     */
    public static BigInteger getSaltWorksSellPrice(GreatTradeConfig config, GreatTradeSaltWorks saltWorks) {
        return new BigDecimal(saltWorks.getPrice()).multiply(BigDecimal.valueOf(config.getSaltBuyParam().get(0))).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).toBigInteger();
    }

    public static List<SaltWorksResult> calSaltWorksResults(Map<Integer, GreatTradeBeautySkill> skillMap, GreatTradeSimpleStatus status, Map<Integer, GreatTradeSaltWorks> worksMap, GreatTradeConfig config, Random random) {
        List<SaltWorksResult> resultList = new ArrayList<>();
        for (Map.Entry<Integer, GreatTradeSaltWorks> worksEntry : worksMap.entrySet()) {
            GreatTradeSaltWorks saltWorks = worksEntry.getValue();
            int worksReserves = getSaltWorksReserves(skillMap, saltWorks, config);
            if(saltWorks.getSealOrSell() == 1 || worksReserves == 0){
                //查封没有收益
                continue;
            }
            if(saltWorks.getSealOrSell() == 3){
                //已出售
                continue;
            }
            GreatTradeGoodsInfo goodsInfo = config.getGreatTradeGoodsInfo(worksEntry.getKey());
            if(goodsInfo != null) {
                List<Integer> exParamList = StringUtils.stringToIntegerList(goodsInfo.getExParam(), "\\|");
                SaltWorksResult result = new SaltWorksResult(worksEntry.getKey());
                if(saltWorks.getMiningSpeed() == 0 && worksReserves > 0){
                    //自然流失，只算储量
                    result.setRet(0);
                    result.setLose(Math.min(exParamList.get(0), worksReserves));
                    resultList.add(result);
                    continue;
                }
                //查封概率
                //开采风险+开采量
                List<Integer> speedConfigList = config.getExploitSpeedRisk(saltWorks.getMiningSpeed());
                //（基础风险+市场风险）* 开采系数
                int risk = BigDecimal.valueOf((exParamList.get(1) + status.getRisk()) * speedConfigList.get(0)).divide(BigDecimal.valueOf(1000 * 1000), 2, BigDecimal.ROUND_DOWN).multiply(BigDecimal.valueOf(100)).intValue();
                //免查
                int mianCha = getSkillAddition(11, skillMap, saltWorks.getId(), null, config);

                if(random.nextInt(100) < risk && mianCha <= 0){
                    //查封
                    result.setRet(1);
                    resultList.add(result);
                    continue;
                }
                //开采收益
                result.setRet(2);
                //开采量
                int lose = Math.min(speedConfigList.get(1), worksReserves);
                result.setLose(lose);
                BigInteger addSliver = new BigInteger(goodsInfo.getChangeParam()).multiply(BigInteger.valueOf(lose));
                //技能加成
                //int addition = getSkillAddition(11, skillMap, saltWorks.getId(), null, config);
                //if(addition > 0){
                //    addSliver = new BigDecimal(addSliver).multiply(BigDecimal.valueOf(1000 + addition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).toBigInteger();
                //}

                result.setAddSliver(addSliver);
                status.addSellMoney(2, addSliver);
                resultList.add(result);
            }
        }
        return resultList;
    }

    public static int getSkillAddition(int skillId, Map<Integer, GreatTradeBeautySkill> skillMap, Object obj, Random random, GreatTradeConfig config){
        int addition = 0;
        //技能加成
        GreatTradeBeautySkill skill = skillMap.get(skillId);
        if(skill != null){
            addition = config.getSkillAddition(skill.getId(), skill.getTotalLv(), obj, random);
        }
        return addition;
    }

    public static IndustryResult calIndustryProfit(Map<Integer, GreatTradeBeautySkill> beautySkillMap, GreatTradeIndustry industry, List<Map<Integer, Long>> priceMap, GreatTradeConfig config, int curYear, Random random){
        IndustryResult result = new IndustryResult();
        if(industry.getId() > 0 && industry.getShares() > 0){
            GreatTradeGoodsInfo goodsInfo = config.getGreatTradeGoodsInfo(industry.getId());
            if(goodsInfo != null){
                List<Integer> exParamList = StringUtils.stringToIntegerList(goodsInfo.getExParam(), "\\|");
                if(curYear - industry.getStartYear() >= exParamList.get(0)){
                    //过了发展期
                    //收益
                    int addition = getSkillAddition(9, beautySkillMap, null, null, config);

                    int range = exParamList.get(3);
                    if(!exParamList.get(4).equals(range)){
                        range = range + random.nextInt(exParamList.get(4) - range);
                    }
                    result.setIndustryProfit(new BigDecimal(industry.getPrice()).multiply(BigDecimal.valueOf(industry.getShares())).multiply(BigDecimal.valueOf(range)).multiply(BigDecimal.valueOf(1000 + addition)).divide(BigDecimal.valueOf(1000 * 1000), 0, BigDecimal.ROUND_DOWN).toBigInteger());
                }
            }
        }
        return result;
    }

    public static long getCalAblePrestige(GreatTradeSimpleStatus tradeStatus){
        if(tradeStatus.getPrestige() >= 0){
            return tradeStatus.getPrestige();
        }
        return 1L;
    }

    public static long getGoodsNewestPrice(List<Map<Integer, Long>> list, int id){
        if(list.size() == 0){
            return 0;
        }
        Map<Integer, Long>  priceMap = list.get(list.size() - 1);
        return priceMap.getOrDefault(id, 0L);
    }

    public static long getGoodsBrokenPrice(GreatTradeGoodsInfo goodsInfo, int addition){
        return new BigDecimal(goodsInfo.getBasePrice()).multiply(BigDecimal.valueOf(addition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).longValue();
    }

    public static int getIllWeight(int health, GreatTradeConfig config) {
        int weight = 0; //千分比
        for (String s : config.getHealthyIllPro()) {
            List<Integer> list = StringUtils.stringToIntegerList(s, ";");
            if(health >= list.get(0)){
                weight = list.get(1);
            }
        }
        return weight;
    }

    /**
     * 每年随机事件
     */
    public static int calYearRandomEvent(GreatTradeSimpleStatus status, GreatTradeConfig config, Random random) {
        int eventId = 0;
        if(status.getRandomEventId() > 0){
            return eventId;
        }
        if(random.nextInt(1000) < config.getEventPro()){
            String eventWeight = null;
            //回合
            int huiHe = Math.max(status.getAge() - config.getBirthOld(), 0);
            for (String eventConfig : config.getEventWeight()) {
                List<String> list = StringUtils.stringToStringList(eventConfig, ";");
                if(huiHe >= Integer.valueOf(list.get(0))){
                    eventWeight = StringUtils.listToString(list.subList(1, list.size()), ";");
                }
            }
            if(!StringUtils.isNullOrEmpty(eventWeight)){
                List<Integer> eventList = new ArrayList<>();
                List<Integer> weightList = new ArrayList<>();
                List<String> list = StringUtils.stringToStringList(eventWeight, ";");
                for (String s : list) {
                    List<Integer> eventWeightList = StringUtils.stringToIntegerList(s, "=");
                    eventList.add(eventWeightList.get(0));
                    weightList.add(eventWeightList.get(1));
                }
                eventId = eventList.get(RandomHelper.getRandomIndexByWeight(weightList, random));
            }
        }
        return eventId;
    }

    /**
     * 寿辰事件
     */
    public static BigInteger calYearBirthEvent(GreatTradeSimpleStatus status, GreatTradeConfig config) {
        int add = 0;
        if((status.getAge() + 1) % 10 == 0){
            for (String range : config.getEventBirthdayMoneyParam()) {
                List<Integer> list = StringUtils.stringToIntegerList(range, ";");
                if(status.getPrestige() >= list.get(0)){
                    add = list.get(1);
                }
            }
        }
        return toPositive(new BigDecimal(getCalAbleAssets(status.getAssets())).multiply(BigDecimal.valueOf(add)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).toBigInteger());
    }

    /**
     * 保底资产
     */
    public static BigInteger getCalAbleAssets(String assets){
        BigInteger val = new BigInteger(assets);
        if(val.compareTo(BigInteger.ZERO) >= 0){
            return val;
        }
        return BigInteger.ONE;
    }

    public static BigInteger toPositive(BigInteger value){
        if(value == null){
            return BigInteger.ZERO;
        }
        if(value.compareTo(BigInteger.ZERO) < 0){
            return BigInteger.ZERO;
        }
        return value;
    }

    /**
     * 每年产业价格
     */
    public static Map<Integer, Long> initYearMarketIndustryPrice(UserGreatTradeData userData, GreatTradeConfig config, Random random) {
        Map<Integer, Long> lastPrice = new HashMap<>();
        if(userData.getIndustryPrice().size() > 0){
            lastPrice = userData.getIndustryPrice().get(userData.getIndustryPrice().size() - 1);
        }
        Map<Integer, Long> goodsPrice = config.randomIndustryPrice(lastPrice, random);
        return goodsPrice;
    }

    public static void addYearMarketIndustryPrice(UserGreatTradeData userData, Map<Integer, Long> goodsPrice){
        if(userData.getIndustryPrice().size() > 2){
            userData.getIndustryPrice().remove(0);
        }
        userData.getIndustryPrice().add(goodsPrice);
        userData.setUpdateOption();
    }

    /**
     * 每年行商市场价格
     */
    public static Map<Integer, Integer> initYearMarketGoodsPrice(UserGreatTradeData userData, GreatTradeSimpleStatus simpleStatus, GreatTradeConfig config, Random random) {
        //市场可以出现的商品数量
        int m;
        if(config.getBuyRandomNumList().get(0).equals(config.getBuyRandomNumList().get(1))){
            m = config.getBuyRandomNumList().get(0);
        }else {
            m = config.getBuyRandomNumList().get(0) + random.nextInt(config.getBuyRandomNumList().get(1) - config.getBuyRandomNumList().get(0));
        }
        //背包已购买的商品
        List<Integer> buyList = new ArrayList<>();
        for (GreatTradeGoods goods : userData.getGoodsList()) {
            if(goods.getNum() > 0) {
                buyList.add(goods.getId());
            }
        }
        //背包今年可出现的商品
        List<Integer> displayList = new ArrayList<>();
        //小鹿女技能加成-出现概率加成

        int displayAddition = GreatTradeMgr.getSkillAddition(4, userData.getBeautyMap(), 0, null, config);
        int upAddition = GreatTradeMgr.getSkillAddition(4, userData.getBeautyMap(), 1, null, config);

        //优先背包中商品
        if(displayAddition > 0) {
            for (int id : buyList) {
                if (random.nextInt(1000) < displayAddition + config.getBuyRandomPro()) {
                    displayList.add(id);
                }
            }
        }
        //背包今年可出现的数量
        int n = displayList.size();
        //最终出现的商品列表
        List<Integer> resultList = new ArrayList<>();
        if(m == n){
            resultList.addAll(displayList);
        }else if(m < n){
            //改为按价格高的优先
            List<GreatTradeGoodsInfo> poolList = new ArrayList<>();
            for (Integer id : displayList) {
                poolList.add(config.getGreatTradeGoodsInfo(id));
            }
            poolList.sort((o1, o2) -> new BigInteger(o2.getBasePrice()).compareTo(new BigInteger(o1.getBasePrice())));
            while (poolList.size() > 0 && resultList.size() < m){
                //resultList.add(displayList.remove(random.nextInt(displayList.size())));
                resultList.add(poolList.remove(0).getId());
            }
        }else {
            if(displayAddition > 0) {
                for (int goodsId : buyList) {
                    if (!displayList.contains(goodsId) && displayList.size() < m) {
                        displayList.add(goodsId);
                    }
                }
            }
            resultList.addAll(displayList);
            List<GreatTradeGoodsInfo> allGoods = config.getGoodsInfoListByAgeAndAssets(simpleStatus);
            allGoods.removeIf(info -> displayList.contains(info.getId()));
            while (m > resultList.size() && allGoods.size() > 0){
                GreatTradeGoodsInfo goodsInfo = allGoods.remove(random.nextInt(allGoods.size()));
                resultList.add(goodsInfo.getId());
            }
        }

        //先随机背包中的
        List<Integer> buyListDisplay = new ArrayList<>();
        Iterator<Integer> iterator = resultList.iterator();
        while (iterator.hasNext()){
            int tempId = iterator.next();
            if(buyList.contains(tempId)){
                buyListDisplay.add(tempId);
                iterator.remove();
            }
        }

        Map<Integer, Integer> goodsPrice = config.randomGoodsPrice(resultList, 0, random);
        //背包中的有涨概率加成
        goodsPrice.putAll(config.randomGoodsPrice(buyListDisplay, upAddition, random));

        boolean hasMin = false;
        //是否有大涨的价格
        for (Map.Entry<Integer, Integer> entry : goodsPrice.entrySet()) {
            int id = entry.getKey();
            int price = entry.getValue();
            GreatTradeGoodsInfo goodsInfo = config.getGreatTradeGoodsInfo(id);
            List<String> changeParamList = StringUtils.stringToStringList(goodsInfo.getChangeParam(), "\\|");
            List<Integer> changeParam2 = StringUtils.stringToIntegerList(changeParamList.get(1), ";");
            //平价最高
            int max = new BigDecimal(goodsInfo.getBasePrice()).multiply(BigDecimal.valueOf(changeParam2.get(1))).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).intValue();
            if(price >= max){
                int addition = getSkillAddition(13, userData.getBeautyMap(), null, null, config);
                if(addition > 0){
                    int newPrice = BigDecimal.valueOf(price * (1000 + addition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).intValue();
                    goodsPrice.put(id, newPrice);
                }
            }
            //评价最低
            int min = new BigDecimal(goodsInfo.getBasePrice()).multiply(BigDecimal.valueOf(changeParam2.get(0))).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).intValue();
            if(price < min){
                hasMin = true;
            }
        }
        //第一年必有大跌
        if(!hasMin && simpleStatus.getCurYear() == 1){
            List<Integer> goodsList = new ArrayList<>(goodsPrice.keySet());
            int id = goodsList.get(random.nextInt(goodsList.size()));
            GreatTradeGoodsInfo goodsInfo = config.getGreatTradeGoodsInfo(id);
            if(goodsInfo != null) {
                List<String> rangeList = StringUtils.stringToStringList(goodsInfo.getChangeParam(), "\\|");
                List<Integer> range = StringUtils.stringToIntegerList(rangeList.get(0), ";");
                int addition = range.get(0) + random.nextInt(range.get(1) - range.get(0));
                goodsPrice.put(goodsInfo.getId(), new BigDecimal(goodsInfo.getBasePrice()).multiply(BigDecimal.valueOf(addition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).intValue());
            }
        }

        Map<Integer, Integer> lastYearPrice = userData.getGoodsPriceList();
        for (Map.Entry<Integer, Integer> entry : lastYearPrice.entrySet()) {
            List<Integer> list = userData.getGoodsHistoryPrice().computeIfAbsent(entry.getKey(), k -> new ArrayList<>());
            if(list.size() >= 3){
                list.remove(0);
            }
            list.add(entry.getValue());
        }
        return goodsPrice;
    }

    /**
     * 记录每年收益
     */
    public static void addThisYearProfit(UserGreatTradeData userData, Map<Integer, String> profitMap){
        if(userData.getProfitMap().size() > 1){
            userData.getProfitMap().remove(0);
        }
        if(profitMap.size() > 0) {
            userData.getProfitMap().add(profitMap);
        }
        userData.setUpdateOption();
    }

    public static GreatTradeSimpleStatus initTradeBaseData(UserGreatTradeData userData, GreatTradeConfig config, Random random) {
        initTradeData(userData);
        int size = config.getBirthFamily().size();
        // 出生/家境
        GreatTradeSimpleStatus tradeStatus = new GreatTradeSimpleStatus();
        tradeStatus.setTradeFinish(false);
        tradeStatus.setBirth(config.getBirthFamily().get(random.nextInt(size)));
        //tradeStatus.setBirth(1004);
        GreatTradeSkillsInfo skillsInfo = config.getGreatTradeSkillsInfo(tradeStatus.getBirth());
        // 年龄
        tradeStatus.setAge(config.getBirthOld());
        // 额外健康上限
        tradeStatus.setExMaxHealth(config.getHealthyMax());
        // 健康值
        tradeStatus.setHealth(GreatTradeMgr.getUserMaxHealth(userData, config, tradeStatus.getExMaxHealth()));
        // 现银
        BigInteger silver = BigInteger.valueOf(config.getBirthMoney());

        //美女技能-现银
        silver = silver.add(BigInteger.valueOf(getSkillAddition(1, userData.getBeautyMap(), null, null, config)));

        // 名望/声望
        tradeStatus.setPrestige(0L);

        if(1001 == tradeStatus.getBirth()){
            tradeStatus.setAge(skillsInfo.getSkillParam().get(0));
        }else if(1002 == tradeStatus.getBirth()){
            silver = silver.add(BigInteger.valueOf(skillsInfo.getSkillParam().get(0)));
            tradeStatus.setPrestige(tradeStatus.getPrestige() + skillsInfo.getSkillParam().get(1));
        }else if(1003 == tradeStatus.getBirth()){
            silver = silver.add(BigInteger.valueOf(skillsInfo.getSkillParam().get(0)));
            tradeStatus.setPrestige(tradeStatus.getPrestige() + skillsInfo.getSkillParam().get(1));
        }else if(1004 == tradeStatus.getBirth()){
            tradeStatus.setExMaxHealth(tradeStatus.getExMaxHealth() + skillsInfo.getSkillParam().get(0));
            tradeStatus.setHealth(GreatTradeMgr.getUserMaxHealth(userData, config, tradeStatus.getExMaxHealth()));
        }

        // 称号
        tradeStatus.setTitle(config.getTitleInfoList().get(0).getId());
        // 当前年限
        tradeStatus.setCurYear(1);
        // 仓库容量
        tradeStatus.setBagCap(config.getBagCellBiginNum());
        //外出遭遇次数
        tradeStatus.setOutTimes(1);

        tradeStatus.setSilver(silver.toString());
        // 资产
        tradeStatus.setAssets(tradeStatus.getSilver());
        tradeStatus.setLastAssets(tradeStatus.getAssets());
        tradeStatus.setStartTime(DateHelper.getCurrentSecond());
        return tradeStatus;
    }

    public static int getUserBagCap(UserGreatTradeData userData, GreatTradeConfig config) {
        int cap = userData.getTradeStatus().getBagCap();
        cap += getSkillAddition(2, userData.getBeautyMap(), null, null, config);
        return cap;
    }

    public static int getUserMaxAge(UserGreatTradeData userData, GreatTradeConfig config){
        int max = config.getDieOld();
        max += getSkillAddition(8, userData.getBeautyMap(), null, null, config);
        return max;
    }

    public static int getSaltWorksReserves(UserGreatTradeData userData, GreatTradeSaltWorks saltWorks, GreatTradeConfig config) {
        int addition = getSkillAddition(10, userData.getBeautyMap(), null, null, config);
        return saltWorks.getReserves() + addition / 10 - saltWorks.getUse();
    }

    public static int getSaltWorksReserves(Map<Integer, GreatTradeBeautySkill> skillMap, GreatTradeSaltWorks saltWorks, GreatTradeConfig config) {
        int addition = getSkillAddition(10, skillMap, null, null, config);
        return saltWorks.getReserves() + addition / 10 - saltWorks.getUse();
    }

    public static int getUserMaxHealth(UserGreatTradeData userData, GreatTradeConfig config, int base) {
        int addition = getSkillAddition(8, userData.getBeautyMap(), null, null, config);
        return base + addition;
    }

    public static int getUserMaxHealth(Map<Integer, GreatTradeBeautySkill> beautySkillMap, GreatTradeConfig config, int base) {
        int addition = getSkillAddition(8, beautySkillMap, null, null, config);
        return base + addition;
    }

    public static void initTradeData(UserGreatTradeData tmpUserData) {
        tmpUserData.setGoodsList(new ArrayList<>());
        tmpUserData.setGoodsPriceList(new HashMap<>());
        tmpUserData.setGoodsHistoryPrice(new HashMap<>());
        tmpUserData.setIndustryPrice(new ArrayList<>());
        tmpUserData.setSaltWorksMap(new HashMap<>());
        tmpUserData.setMilepostRecordList(new ArrayList<>());
        tmpUserData.setIndustry(new GreatTradeIndustry());
        tmpUserData.setTradeStatus(new GreatTradeSimpleStatus());
        tmpUserData.setProfitMap(new ArrayList<>());
    }

    public static int getBagGoodsCount(UserGreatTradeData userData) {
        int sum = 0;
        for (int i = 0; i < userData.getGoodsList().size(); i++) {
            GreatTradeGoods goods = userData.getGoodsList().get(i);
            sum += goods.getNum();
        }
        return sum;
    }

    public static GreatTradeGoods getBagGoods(UserGreatTradeData userData, int id) {
        for (int i = 0; i < userData.getGoodsList().size(); i++) {
            GreatTradeGoods goods = userData.getGoodsList().get(i);
            if(goods.getId() == id){
                return goods;
            }
        }
        return null;
    }

    /**
     * 完成外出事件，且统计
     */
    public static void completeAreaEvent(GamePlayer player, UserGreatTradeData userData, int eventId, GreatTradeConfig config){
        int num = userData.getEventMap().getOrDefault(eventId, 0);
        num++;
        userData.getEventMap().put(eventId, num);
        statAreaEventNum(player, userData, eventId, config);
        userData.getTradeStatus().addAreaEvents(eventId);
        player.getModule(GreatTradeModule.class).checkSkillUnlock("5", "" + eventId, "" + num, config);
    }

    private static void statAreaEventNum(GamePlayer player, UserGreatTradeData userData, int eventId, GreatTradeConfig config) {
        GreatTradeEventInfo eventInfo = config.getGreatTradeEventInfo(eventId);
        if(eventInfo != null){
            int areaId = 0;
            if(eventInfo.getType() == 3 || eventInfo.getType() == 4){
                areaId = 1; //医馆
            }else if(eventInfo.getType() == 1 || eventInfo.getType() == 2){
                areaId = 2; //酒楼
            }else if(eventInfo.getType() == 6){
                areaId = 4; //黑市
            } else if(eventInfo.getType() == 5){
                areaId = 3; //御街
            }
            int num = userData.getEventMap().getOrDefault(areaId, 0);
            userData.getEventMap().put(areaId, num + 1);
            //统计事件类型
            int count = userData.getEventMap().getOrDefault(100, 0);
            count = count | 1 << (eventInfo.getType() -1);
            userData.getEventMap().put(100, count);

            //单局触发所有外出遭遇
            int val = userData.getEventMap().getOrDefault(100, 0);
            if( val == (1 << 6) - 1){
                player.notifyListener(eGamePlayerEventType.GreatTradeMerchant.getValue(), new ValueFourParamArgs(BigInteger.ONE, 9));
            }
        }
    }

    public static int getMaxOutArea(UserGreatTradeData userData){
        int areaId = 0;
        int times = 0;
        int num = 4;
        for (int i = 1; i <= num; i++) {
            if(userData.getEventMap().containsKey(i)){
                int tempTimes = userData.getEventMap().get(i);
                if(tempTimes > times){
                    times = tempTimes;
                    areaId = i;
                }
            }
        }
        return areaId;
    }

    /**
     * 完成外出事件(多个事件)，且统计
     */
    public static void completeAreaEvent(GamePlayer player, UserGreatTradeData userData, List<Integer> eventIdList, GreatTradeConfig config){
        for (int eventId : eventIdList) {
            int num = userData.getEventMap().getOrDefault(eventId, 0);
            num++;
            userData.getEventMap().put(eventId, num);
            userData.getTradeStatus().addAreaEvents(eventId);
            statAreaEventNum(player, userData, eventId, config);
            //player.notifyListener(eGamePlayerEventType.GreatTradeBeautyTravel.getValue(), new ValueFourParamArgs(BigInteger.valueOf(num), 5, 0, eventId));
        }
        //userData.setAreaEvent(new GreatTradeAreaEvent());
    }

    /**
     * 完成随机事件，且统计
     */
    public static void completeRandomEvent(GamePlayer player, UserGreatTradeData userData, GreatTradeSimpleStatus tradeStatus) {
        int randomEventId = tradeStatus.getRandomEventId();
        if(randomEventId <= 0){
            return;
        }
        int num = userData.getEventMap().getOrDefault(randomEventId, 0);
        num++;
        userData.getEventMap().put(randomEventId, num);
        player.getModule(GreatTradeModule.class).checkSkillUnlock("5", "" + randomEventId, "" + num, config);
        int allRandomNum = userData.getEventMap().getOrDefault(7, 0);
        allRandomNum++;
        userData.getEventMap().put(7, allRandomNum);
        userData.setUpdateOption();
        player.notifyListener(eGamePlayerEventType.GreatTradeMerchant.getValue(), new ValueFourParamArgs(BigInteger.valueOf(allRandomNum), 4));
        player.getModule(GreatTradeModule.class).checkSkillUnlock("6", "0", "" + allRandomNum, config);
    }
}
